package com.lineage.server.clientpackets;

import com.add.AutoAttackUpdateNew;
import com.lineage.config.ConfigGuaji;
import com.lineage.config.ConfigOther;
import com.lineage.echo.ClientExecutor;
import com.lineage.server.datatables.PolyTable;
import com.lineage.server.datatables.SkillsTable;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.L1CastleLocation;
import com.lineage.server.model.L1PolyMorph;
import com.lineage.server.model.skill.L1SkillUse;
import com.lineage.server.serverpackets.S_Paralysis;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.S_SystemMessage;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Skills;
import com.lineage.server.utils.CheckUtil;
import com.lineage.server.world.World;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class C_UseSkill extends ClientBasePacket {
  private static final Log _log = LogFactory.getLog(C_UseSkill.class);
  
  private static final int[] _cast_with_invis = new int[] { 
      1, 2, 3, 5, 8, 9, 12, 13, 14, 19, 
      21, 26, 31, 32, 35, 37, 42, 43, 44, 48, 
      49, 52, 
      54, 55, 57, 60, 61, 63, 68, 69, 
      72, 73, 75, 78, 79, 88, 89, 90, 91, 97, 
      98, 99, 100, 101, 102, 104, 105, 
      106, 107, 109, 
      110, 111, 113, 114, 115, 116, 117, 118, 129, 130, 
      131, 133, 134, 137, 138, 146, 147, 148, 
      149, 150, 
      151, 155, 156, 158, 159, 163, 164, 165, 166, 168, 
      169, 170, 171, 175, 176, 181, 185, 190, 195, 
      201, 
      204, 209, 211, 214, 216, 219 };
  
  public void start(byte[] decrypt, ClientExecutor client) {
    try {
      read(decrypt);
      L1PcInstance pc = client.getActiveChar();
      if (!pc.isDead() && 
        !pc.isTeleport() && 
        !pc.isPrivateShop() && 
        !pc.hasSkillEffect(4017))
        if (pc.getInventory().getWeight240() >= 197) {
          pc.sendPackets((ServerBasePacket)new S_ServerMessage(316));
        } else if (pc.get_MOVE_STOP()) {
          pc.setTeleport(false);
          pc.sendPackets((ServerBasePacket)new S_Paralysis(7, false));
        } else if (!pc.getMap().isUsableSkill()) {
          pc.sendPackets((ServerBasePacket)new S_ServerMessage(563));
        } else {
          int result;
          boolean isError = false;
          boolean isError2 = false;
          int polyId = pc.getTempCharGfx();
          L1PolyMorph poly = PolyTable.get().getTemplate(polyId);
          if (poly != null && !poly.canUseSkill())
            isError = true; 
          if (pc.isParalyzed() && !isError)
            isError = true; 
          if (pc.hasSkillEffect(64) && !isError)
            isError = true; 
          if (pc.hasSkillEffect(161) && !isError)
            isError = true; 
          if (pc.hasSkillEffect(1007) && !isError)
            isError = true; 
          if (pc.isParalyzedX() && !isError)
            isError = true; 
          if (isError) {
            pc.sendPackets((ServerBasePacket)new S_Paralysis(7, false));
            pc.sendPackets((ServerBasePacket)new S_ServerMessage(285));
            return;
          } 
          int row = readC();
          int column = readC();
          int skillId = (row << 3) + column + 1;
          int[] MAP_IDSKILL = ConfigOther.MAP_IDSKILL;
          int[] MAP_SKILL = ConfigOther.MAP_SKILL;
          int array[], i = (array = MAP_IDSKILL).length;
          int j = 0;
          while (j < i) {
            int mapid = array[j];
            int array2[], length = (array2 = MAP_SKILL).length;
            int m = 0;
            while (m < length) {
              int mapskill = array2[m];
              if (pc.getMapId() == mapid && skillId == mapskill) {
                pc.sendPackets((ServerBasePacket)new S_ServerMessage("此地图无法使用此魔法"));
                return;
              } 
              m++;
            } 
            j++;
          } 
          int[] bow_GFX_Arrow = ConfigGuaji.Guaji_map_stopskill;
          int array3[], length2 = (array3 = bow_GFX_Arrow).length;
          i = 0;
          while (i < length2) {
            int gfx = array3[i];
            if (skillId == gfx && pc.isActived()) {
              pc.sendPackets((ServerBasePacket)new S_ServerMessage("内挂中禁止施放此魔法"));
              return;
            } 
            i++;
          } 
          boolean castle_area = L1CastleLocation.checkInAllWarArea(pc.getX(), pc.getY(), 
              pc.getMapId());
          int[] bow_GFX_Arrow2 = ConfigOther.WAR_DISABLE_SKILLS;
          int array4[], k = (array4 = bow_GFX_Arrow2).length;
          int l = 0;
          while (l < k) {
            int gfx2 = array4[l];
            if (skillId == gfx2 && castle_area && pc.castleWarResult()) {
              pc.sendPackets((ServerBasePacket)new S_ServerMessage("战争旗帜内禁止使用此魔法"));
              return;
            } 
            l++;
          } 
          if (skillId > 239)
            return; 
          if (skillId < 0)
            return; 
          if ((pc.isInvisble() || pc.isInvisDelay()) && !isInvisUsableSkill(skillId)) {
            pc.sendPackets((ServerBasePacket)new S_ServerMessage(1003));
            return;
          } 
          if (!pc.isSkillMastery(skillId))
            return; 
          CheckUtil.isUserMap(pc);
          String charName = new String();
          int targetId = 0;
          int targetX = 0;
          int targetY = 0;
          if (SkillsTable.get().getTemplate(skillId).getActionId() == 18) {
            result = pc.getAcceleratorChecker().checkInterval(
                AcceleratorChecker.ACT_TYPE.SPELL_DIR);
          } else {
            result = pc.getAcceleratorChecker().checkInterval(
                AcceleratorChecker.ACT_TYPE.SPELL_NODIR);
          } 
          if (result == 2) {
            _log.error("要求角色技能攻击:速度异常(" + pc.getName() + ")");
            return;
          } 
          if (skillId == 18 && pc.hasSkillEffect(6931)) {
            pc.killSkillEffectTimer(6931);
            pc.setSkillEffect(6932, 2000);
          } 
          if (decrypt.length > 4)
            try {
              if (skillId == 116 || skillId == 118) {
                String[] tempName = readS().split("\\[");
                charName = tempName[0];
              } else if (skillId == 113) {
                targetId = readD();
                targetX = readH();
                targetY = readH();
                pc.setText(readS());
              } else if (skillId == 5 || skillId == 69) {
                targetId = readH();
                targetX = readH();
                targetY = readH();
              } else if (skillId == 58 || skillId == 63) {
                targetX = readH();
                targetY = readH();
              } else if (skillId == 51) {
                if (pc.getInventory().checkEquipped(20284) || 
                  pc.getInventory().checkEquipped(120284)) {
                  int summonId = readD();
                  pc.setSummonId(summonId);
                } else {
                  targetId = readD();
                } 
              } else {
                targetId = readD();
                targetX = readH();
                targetY = readH();
              } 
            } catch (Exception exception) {} 
          if (pc.IsAttackSkill()) {
            if (AutoAttackUpdateNew.getInstance().isAttackSkill(skillId)) {
              if (!pc.isAttackSkillList(Integer.valueOf(skillId))) {
                if (pc.AttackSkillSize() < 5) {
                  pc.setAttackSkillList(Integer.valueOf(skillId));
                  L1Skills skill = SkillsTable.get().getTemplate(skillId);
                  String name = skill.getName();
                  pc.sendPackets((ServerBasePacket)new S_SystemMessage("成功将[" + name + "]登录至自动施放清单内"));
                  if (pc.get_other1().get_type46() == 0) {
                    pc.get_other1().set_type46(skillId);
                  } else if (pc.get_other1().get_type47() == 0) {
                    pc.get_other1().set_type47(skillId);
                  } else if (pc.get_other1().get_type48() == 0) {
                    pc.get_other1().set_type48(skillId);
                  } else if (pc.get_other1().get_type49() == 0) {
                    pc.get_other1().set_type49(skillId);
                  } else if (pc.get_other1().get_type50() == 0) {
                    pc.get_other1().set_type50(skillId);
                  } 
                } else {
                  pc.sendPackets((ServerBasePacket)new S_SystemMessage("内挂选单内可登录技能最多5各"));
                } 
              } else {
                pc.sendPackets((ServerBasePacket)new S_SystemMessage("此技能已登录于内挂施放技能选单内"));
              } 
            } else {
              pc.sendPackets((ServerBasePacket)new S_SystemMessage("此技能无法登录.请重新施放要[攻击]技能"));
            } 
            pc.setAttackSkill(false);
            return;
          } 
          if (pc.hasSkillEffect(78)) {
            pc.killSkillEffectTimer(78);
            pc.startHpRegeneration();
            pc.startMpRegeneration();
          } 
          pc.killSkillEffectTimer(32);
          try {
            if (skillId == 116 || skillId == 118) {
              if (charName.isEmpty())
                return; 
              L1PcInstance target = World.get().getPlayer(charName);
              if (target == null) {
                pc.sendPackets((ServerBasePacket)new S_ServerMessage(73, charName));
                return;
              } 
              if (pc.getClanid() != target.getClanid()) {
                pc.sendPackets((ServerBasePacket)new S_ServerMessage(414));
                return;
              } 
              targetId = target.getId();
              if (skillId == 116) {
                int callClanId = pc.getCallClanId();
                if (callClanId == 0 || callClanId != targetId) {
                  pc.setCallClanId(targetId);
                  pc.setCallClanHeading(pc.getHeading());
                } 
              } 
            } 
            if (pc.isWizard() && pc.getlogpcpower_SkillFor5() != 0) {
              L1Skills _skill = SkillsTable.get().getTemplate(skillId);
              if (_skill.getTarget().equals("attack"))
                if (pc.hasSkillEffect(5198)) {
                  if (pc.getEsotericSkill() == skillId) {
                    if (pc.getEsotericCount() < 4) {
                      pc.setEsotericCount(pc.getEsotericCount() + 1);
                      if (pc.getEsotericCount() == 2) {
                        pc.sendPackets((ServerBasePacket)new S_SystemMessage("魔击累积 阶段二已发动！"));
                      } else if (pc.getEsotericCount() == 3) {
                        pc.sendPackets((ServerBasePacket)new S_SystemMessage("魔击累积 阶段三已发动！"));
                      } else if (pc.getEsotericCount() == 4) {
                        pc.sendPackets((ServerBasePacket)new S_SystemMessage("魔击累积 阶段四已发动！"));
                      } 
                    } else {
                      pc.sendPackets((ServerBasePacket)new S_SystemMessage("魔击累积维持"));
                    } 
                  } else {
                    pc.setEsotericSkill(skillId);
                    pc.setEsotericCount(1);
                    pc.sendPackets((ServerBasePacket)new S_SystemMessage("魔击累积 阶段一已发动！"));
                  } 
                  pc.setSkillEffect(5198, 2000);
                } else {
                  pc.setEsotericSkill(skillId);
                  pc.setEsotericCount(1);
                  pc.setSkillEffect(5198, 2000);
                  pc.sendPackets((ServerBasePacket)new S_SystemMessage("魔击累积 阶段一 已发动！"));
                }  
            } 
            L1SkillUse l1skilluse = new L1SkillUse();
            l1skilluse.handleCommands(pc, skillId, targetId, targetX, targetY, 0, 0);
          } catch (Exception exception) {}
          return;
        }  
      return;
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } finally {
      over();
    } 
  }
  
  private boolean isInvisUsableSkill(int useSkillid) {
    int cast_with_invis[], length = (cast_with_invis = _cast_with_invis).length;
    int i = 0;
    while (i < length) {
      int skillId = cast_with_invis[i];
      if (skillId == useSkillid)
        return true; 
      i++;
    } 
    return false;
  }
  
  public String getType() {
    return getClass().getSimpleName();
  }
}
